﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
using Dare.Utilities.IO;

namespace Dare.Utilities.Net.Ftp
{
    public class FtpItemParser
    {
        public static List<FtpItem> ParseItems(string val)
        {
            string[] items = val.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
            List<FtpItem> list = new List<FtpItem>(items.Length);
            for (int i = 0; i < items.Length; i++)
            {
                FtpItem item = InnerParseItem(items[i].Trim());
                if (item != null)
                {
                    list.Add(item);
                }
            }
            return list;
        }

        public static FtpItem ParseItem(string val)
        {
            if (val == null) return null;
            val = val.Trim();
            if (val == String.Empty) return null;
            return InnerParseItem(val);
        }

        private static FtpItem InnerParseItem(string val)
        {
            FtpItem item = null;
            string[] segments = val.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
            Char firstChar = Char.ToLower(segments[0][0]);
            UnixFileAttribute attrib = null;

            if (segments.Length >= 9 && UnixFileAttribute.TryParse(segments[0], out attrib))       //UNIX格式
            {
                /* UNIX-style listing, without inum and without blocks */
                /* "-rw-r--r--   1 root     other        531 Jan 29 03:26 README" */
                /* "dr-xr-xr-x   2 root     other        512 Apr  8  1994 etc" */
                /* "dr-xr-xr-x   2 root     512 Apr  8  1994 etc" */
                /* "lrwxrwxrwx   1 root     other          7 Jan 25 00:17 bin -> usr/bin" */
                /* Also produced by Microsoft's FTP servers for Windows: */
                /* "----------   1 owner    group         1803128 Jul 10 10:18 ls-lR.Z" */
                /* "d---------   1 owner    group               0 May  9 19:45 Softlib" */
                /* Also WFTPD for MSDOS: */
                /* "-rwxrwxrwx   1 noone    nogroup      322 Aug 19  1996 message.ftp" */
                /* Also NetWare: */
                /* "d [R----F--] supervisor            512       Jan 16 18:53    login" */
                /* "- [R----F--] rhesus             214059       Oct 20 15:27    cx.exe" */
                /* Also NetPresenz for the Mac: */
                /* "-------r--         326  1391972  1392298 Nov 22  1995 MegaPhone.sit" */
                /* "drwxrwxr-x               folder        2 May 10  1996 network" */

                //文件类型
                switch (attrib.FileType)
                {
                    case UnixFileType.Directory:
                        item = new FtpDirectoryItem();
                        break;
                    case UnixFileType.File:
                        item = new FtpFileItem();
                        break;
                    default:
                        item = new FtpOtherUnixFileItem();
                        break;
                }
                //文件属性
                item.RawAttributes = segments[0];
                item.Attributes = attrib;

                //用户和组
                item.Owner = segments[2];
                item.Group = segments[3];

                //文件大小
                long size = 0;
                if (item is FtpFileItem && long.TryParse(segments[4], out size))
                {
                    (item as FtpFileItem).Size = size;
                }

                //修改日期
                item.Date = DateTime.ParseExact(segments[5] + " " + segments[6] + " " + segments[7],
                    new string[] { "MMM d HH:mm", "MMM d yyyy" }, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal | DateTimeStyles.AllowWhiteSpaces);

                //文件名
                item.Name = String.Join(" ", segments, 8, segments.Length - 8);
            }
            else if (segments.Length >= 4 && Char.IsDigit(segments[0][0]))      //MSDOS格式
            {
                /* MSDOS format */
                /* 04-27-00  09:09PM       <DIR>          licensed */
                /* 07-18-00  10:16AM       <DIR>          pub */
                /* 04-14-00  03:47PM                  589 readme.htm */
                
                //修改日期
                DateTime date = DateTime.ParseExact(segments[0] + " " + segments[1],
                    new string[] { "MM-dd-yy hh:mmtt" }, null, DateTimeStyles.AssumeLocal | DateTimeStyles.AllowWhiteSpaces);

                //文件大小，并确定文件还是目录
                long size = 0;
                if (long.TryParse(segments[2], out size))
                {
                    item = new FtpFileItem();
                    (item as FtpFileItem).Size = size;
                }
                else if (String.Compare(segments[2], "<DIR>", StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    item = new FtpDirectoryItem();
                }

                //修改日期付值
                item.Date = date;

                //文件名
                item.Name = String.Join(" ", segments, 3, segments.Length - 3);

            }

            return item;
        }
    }
}
